package com.lt.flashcard.model.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bson.types.ObjectId;

import com.google.code.morphia.dao.BasicDAO;
import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.EmailQueue;
import com.lt.flashcard.model.entity.FlashcardSet;
import com.lt.flashcard.model.entity.Medal;
import com.lt.flashcard.model.entity.User;

/**
 * A service to generate and send email
 * 
 * @author ocsen
 * 
 */
public class EmailService {

    /**
     * Send invitation email to user
     * 
     * @param fromEmail
     * @param fromName
     * @param emails
     *            List of target email address
     * @param message
     *            The invitation message
     */
    public void sendEmailInviteFriend(String fromEmail, String fromName, List<String> emails, String message) {
        // TODO use producer-consumer model for better performance
        TemplateService tsrv = Repository.getInstance().getTemplateService();
        List<String[]> parsedString = new ArrayList<String[]>();// toemail, subject, message

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("cantreademail", "http://google.com");
        data.put("fromname", fromName);
        data.put("fromemail", fromEmail);
        data.put("message", message);

        for (String email : emails) {
            data.put("targetname", email);
            data.put("registerlink", "registerlink");
            String msg = tsrv.parseTemplate("invitefriend", data);
            parsedString.add(new String[] { email, "Mời tham gia mạng flashcard", msg });
        }
        sendEmail(parsedString);
    }

    /**
     * Send welcome email to new account
     * 
     * @param name
     * @param email
     */
    public void sendEmailWelcome(String name, String email) {
        TemplateService tsrv = Repository.getInstance().getTemplateService();
        List<String[]> parsedString = new ArrayList<String[]>();// toemail, subject, message

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("cantreademail", "http://google.com");
        data.put("username", name);
        data.put("email", email);
        data.put("loginlink", Utility.getServerUrl().concat("/").concat("login.zul"));
        String msg = tsrv.parseTemplate("wellcome", data);
        parsedString.add(new String[] { email, "Chào mừng", msg });
        sendEmail(parsedString);
    }

    /**
     * Send welcome email to new account
     * 
     * @param name
     * @param email
     */
    public void sendEmailWelcomeRestful(String name, String email, String templateRootPath) {
        TemplateService tsrv = Repository.getInstance().getTemplateService(templateRootPath);
        List<String[]> parsedString = new ArrayList<String[]>();// toemail, subject, message

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("cantreademail", "http://google.com");
        data.put("username", name);
        data.put("email", email);
        data.put("loginlink", Utility.getServerUrl().concat("/").concat("login.zul"));
        String msg = tsrv.parseTemplate("wellcome", data);
        parsedString.add(new String[] { email, "Chào mừng", msg });
        sendEmail(parsedString);
    }

    /**
     * Do send email reset password
     * 
     * @param name
     * @param email
     * @param code
     */
    public void sendEmailResetPassword(String name, String email, String code) {
        TemplateService tsrv = Repository.getInstance().getTemplateService();
        List<String[]> mails = new ArrayList<String[]>();// toemail, subject, message

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("username", name);
        data.put("email", email);
        data.put("resetlink", Utility.getServerUrl().concat("/").concat(Utility.generateUrl("resetpassword", code, null)));
        String msg = tsrv.parseTemplate("resetpassword", data);
        mails.add(new String[] { email, "Đặt lại password", msg });
        sendEmail(mails);
    }

    /**
     * Do send email reset password for RESTful service
     * 
     * @param name
     * @param email
     * @param code
     */
    public void sendEmailResetPasswordRestful(String name, String email, String code, String templateRootPath) {
        TemplateService tsrv = Repository.getInstance().getTemplateService(templateRootPath);
        List<String[]> mails = new ArrayList<String[]>();// toemail, subject, message

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("username", name);
        data.put("email", email);
        data.put("resetlink", Utility.getServerUrl().concat("/").concat("resetpassword.zul?code=" + code));
        String msg = tsrv.parseTemplate("resetpassword", data);
        mails.add(new String[] { email, "Đặt lại password", msg });
        sendEmail(mails);
    }

    /**
     * Send email to set new password when changing to new system
     * 
     * @param name
     * @param email
     * @param code
     */
    public void sendEmailNewSystem(String name, String email, String code) {
        TemplateService tsrv = Repository.getInstance().getTemplateService();
        List<String[]> mails = new ArrayList<String[]>();// toemail, subject, message

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("username", name);
        data.put("email", email);
        data.put("link", Utility.getServerUrl().concat("/").concat(Utility.generateUrl("resetpassword", code, null)));
        String msg = tsrv.parseTemplate("newsystem", data);
        mails.add(new String[] { email, "Nâng cấp hệ thống", msg });
        sendEmail(mails);
    }

    /**
     * Send email to share a flashcardset
     * 
     * @param from
     * @param toEmail
     */
    public void sendEmailShareSet(User from, String toEmail, FlashcardSet set) {
        TemplateService tsrv = Repository.getInstance().getTemplateService();
        List<String[]> mails = new ArrayList<String[]>();// toemail, subject, message

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("toemail", toEmail);
        data.put("fromname", from.getUsername());
        data.put("fromemail", from.getEmail());
        data.put("seturl", Utility.generateShareLink(set));
        data.put("setname", set.getName());
        data.put("setdescription", set.getDescription());
        data.put("setauthor", set.getAuthor().getUsername());
        data.put("setnumofcards", set.getTotalflashcards());
        data.put("setimage", Utility.loadImageFromGridFS(set.getImage(), Utility.DEF_FLASHCARDSET));
        data.put("sethasimage", set.hasImage() ? "icon_p.png" : "icon_p_disable.png");
        data.put("sethassound", set.hasSound() ? "icon_p2.png" : "icon_p2_disable.png");
        String msg = tsrv.parseTemplate("shareset", data);
        mails.add(new String[] { toEmail, "Bạn nhận được chia sẻ bộ từ", msg });
        sendEmail(mails);
    }

    /**
     * Send email to share a medal
     * 
     * @param from
     * @param toEmail
     */
    public void sendEmailShareMedal(User from, String toEmail, Medal medal) {
        TemplateService tsrv = Repository.getInstance().getTemplateService();
        List<String[]> mails = new ArrayList<String[]>();// toemail, subject, message

        String link = Utility.generateShareMedalLink(from.getUsername(), medal.getId().toString());

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("toemail", toEmail);
        data.put("fromname", from.getUsername());
        data.put("fromemail", from.getEmail());
        data.put("medalurl", link);
        data.put("medalname", medal.getName());
        String msg = tsrv.parseTemplate("sharemedal", data);
        mails.add(new String[] { toEmail, "Bạn nhận được chia sẻ bộ từ", msg });
        sendEmail(mails);
    }

    /**
     * Send email
     * 
     * @param data
     *            a list of email data, toemail, subject, message
     */
    public void sendEmail(final List<String[]> data) {
        /*
         * Thread thread = new Thread(new Runnable() { public void run() { Properties props = System.getProperties();
         * props.put("mail.smtp.host", Utility.getConfiguration("com.lt.flashcard.smtp_host", ""));
         * props.put("mail.smtp.socketFactory.port", Utility.getConfiguration("com.lt.flashcard.smtp_port", ""));
         * props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.auth",
         * "true"); props.put("mail.smtp.port", Utility.getConfiguration("com.lt.flashcard.smtp_port", ""));
         * 
         * Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected
         * PasswordAuthentication getPasswordAuthentication() { return new
         * PasswordAuthentication(Utility.getConfiguration("com.lt.flashcard.smtp_account", ""),
         * Utility.getConfiguration("com.lt.flashcard.smtp_password", "")); } });
         * 
         * for(String[] d : data) { try { MimeMessage message = new MimeMessage(session); message.setFrom(new
         * InternetAddress(Utility.getConfiguration("com.lt.flashcard.smtp_account", "")));
         * message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(d[0]));
         * message.setHeader("Content-Type", "text/html; charset=UTF-8"); message.setSubject(d[1], "utf-8");
         * message.setContent(d[2], "text/html; charset=utf-8");
         * 
         * Transport.send(message); } catch (MessagingException e) { e.printStackTrace(); } } } }); thread.run();
         */
        BasicDAO<EmailQueue, ObjectId> dao = getEmailQueueDao();

        for (String[] d : data) {
            EmailQueue queue = new EmailQueue();
            queue.setSubject(String.valueOf(d[1]));
            queue.setMessage(String.valueOf(d[2]));
            queue.getTos().add(d[0]);
            dao.save(queue);
        }
    }

    private BasicDAO<EmailQueue, ObjectId> _emaildao = null;

    /**
     * get DAO to interact with database
     * 
     * @return
     */
    public BasicDAO<EmailQueue, ObjectId> getEmailQueueDao() {
        if (_emaildao == null) {
            _emaildao = new BasicDAO<EmailQueue, ObjectId>(EmailQueue.class, Repository.getInstance().getDatastore());
        }
        return _emaildao;
    }

    /**
     * Get entity by id
     * 
     * @param id
     * @return
     */
    public EmailQueue getEmailQueue(String id) {
        return getEmailQueueDao().get(new ObjectId(id));
    }

    /**
     * Save entity to database
     * 
     * @param email
     */
    public void saveEmailQueue(EmailQueue email) {
        getEmailQueueDao().save(email);
    }

    /**
     * Delete entity
     * 
     * @param email
     */
    public void deleteEmailQueue(EmailQueue email) {
        getEmailQueueDao().delete(email);
    }
}
